package cn.breeze.basic.service.impl;

import cn.breeze.basic.constant.BaseConstants;
import cn.breeze.basic.exception.BusinessException;
import cn.breeze.basic.utils.SendComplexEmails;
import cn.breeze.basic.utils.StrUtils;
import cn.breeze.basic.utils.VerifyCodeUtils;
import cn.breeze.basic.service.IVerifyCodeService;
import cn.breeze.basic.vo.RegisterVo;
import cn.breeze.user.domain.User;
import cn.breeze.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    /**
    * @Title: graphicsBase64Str
    * @Description: 生成验证码图片字符串
    * @Author: Mr.D
    * @Version: 1.0
    * @Date:  2022/7/5 23:12
    * @Parameters: [verifyCodeKey]
    * @Return java.lang.String
    */
    @Override
    public String graphicsBase64Str(String verifyCodeKey) {
        // 判断参数是否为空
        if (verifyCodeKey == null){
            throw new BusinessException("参数异常，请重新传递参数！");
        }
        // 通过string工具类获取随机字符串
        String imgCode = StrUtils.getComplexRandomString(4);
        // 通过随机字符串生成图片，并转换为base64编码字符串
        String graphicsBase64Strs = VerifyCodeUtils.VerifyCode(100, 40, imgCode);
        // 将随机字符串以verifyCodeKey为key存入redis中
        redisTemplate.opsForValue().set(verifyCodeKey,imgCode,5, TimeUnit.MINUTES);
        Object aa = redisTemplate.opsForValue().get(verifyCodeKey);
        System.out.println(verifyCodeKey);
        System.out.println(aa);
        return graphicsBase64Strs;
    }

    /**
    * @Title: smsCode
    * @Description: 发送手机验证码
    * @Author: Mr.D
    * @Version: 1.0
    * @Date:  2022/7/5 22:57
    * @Parameters: [registerVo]
    * @Return void
    */
    @Override
    public void smsCode(RegisterVo registerVo) {
        // 业务标识键
        String businessKey = registerVo.getBusinessKey();
        // 手机号
        String phone = registerVo.getPhone();
        // 判断参数不能为空
        if (StringUtils.isEmpty(businessKey) ||StringUtils.isEmpty(phone)){
            throw new BusinessException("参数不能为空！");
        }
        if ("register".equals(businessKey)){
            // 用户输入的验证
            String imageCodeValue = registerVo.getImageCodeValue();
            // 验证码key
            String imageCodeKey = registerVo.getImageCodeKey();
            // 根据key获取图形验证码
            Object imgTempCode = redisTemplate.opsForValue().get(imageCodeKey);
            // 判断验证码是否正确
            if (imgTempCode == null || !imageCodeValue.equalsIgnoreCase(imgTempCode.toString())){
                throw new BusinessException("验证码错误，请重新输入");
            }
            // 判断参数不能为空
            if (StringUtils.isEmpty(businessKey) ||StringUtils.isEmpty(phone) || StringUtils.isEmpty(imageCodeValue) || StringUtils.isEmpty(imageCodeKey)){
                throw new BusinessException("参数不能为空！");
            }
            // 根据电话查询用户是否存在
            User user = userMapper.loadByPhone(phone);
            // 判断账号是否已经注册
            if (user != null){
                throw new BusinessException("账号已注册，请直接登录");
            }
            sendCode(BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_PREFIX, phone);
        }else if ("login".equals(businessKey)){
            // 用户输入的验证
            String imageCodeValue = registerVo.getImageCodeValue();
            // 验证码key
            String imageCodeKey = registerVo.getImageCodeKey();
            // 根据key获取图形验证码
            Object imgTempCode = redisTemplate.opsForValue().get(imageCodeKey);
            // 判断验证码是否正确
            if (imgTempCode == null || !imageCodeValue.equalsIgnoreCase(imgTempCode.toString())){
                throw new BusinessException("验证码错误，请重新输入");
            }
            // 判断参数不能为空
            if (StringUtils.isEmpty(businessKey) ||StringUtils.isEmpty(phone) || StringUtils.isEmpty(imageCodeValue) || StringUtils.isEmpty(imageCodeKey)){
                throw new BusinessException("参数不能为空！");
            }
            sendCode(BaseConstants.VerifyCodeConstant.BUSINESS_LOGIN_PREFIX, phone);
        }else if ("binder".equals(businessKey)){
            sendCode(BaseConstants.VerifyCodeConstant.BUSINESS_BINDER_PREFIX, phone);
        }

    }

    public void sendCode(String baseMiddleKey,String phone){
        // 手机验证码redis中的key
        String smsCodeKey = baseMiddleKey + phone;
        // 根据key获取手机验证码
        Object smsCodeValue = redisTemplate.opsForValue().get(smsCodeKey);
        String smsCode = "";
        if (smsCodeValue == null){
            smsCode = StrUtils.getComplexRandomString(4);
        } else {
            String[] smsCodeValueArray = smsCodeValue.toString().split(":");
            Long oldTime = Long.valueOf(smsCodeValueArray[1]);
            Long newTime = System.currentTimeMillis();
            if (newTime - oldTime < 1*60*1000){
                throw new BusinessException("请一分钟后重试！");
            }
            smsCode = smsCodeValueArray[0];
        }
        String newSmsCodeValue = smsCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(smsCodeKey, newSmsCodeValue, 3, TimeUnit.MINUTES);
        // SmsUtils.sendMsg(phone, "您的验证为：" + smsCode);
        System.out.println("你的验证为：" + smsCode);
    }

    /**
    * @Title: emailCode
    * @Description: 发送邮箱验证码
    * @Author: Mr.D
    * @Version: 1.0
    * @Date:  2022/7/6 16:26
    * @Parameters: [registerVo]
    * @Return void
    */
    @Override
    public void emailCode(RegisterVo registerVo) {
        // 邮箱
        String email = registerVo.getEmail();
        // 验证码
        String imageCodeValue = registerVo.getImageCodeValue();
        // 验证码key
        String imageCodeKey = registerVo.getImageCodeKey();
        // 判断参数是否非空
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(imageCodeValue) || StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("参数不能为空！");
        }
        // 根据key获取图形验证码
        Object imgTempCode = redisTemplate.opsForValue().get(imageCodeKey);
        if (imgTempCode == null || !imageCodeValue.equalsIgnoreCase(imgTempCode.toString())){
            throw new BusinessException("验证码错误，请重新输入");
        }
        // 根据email去user表中查
        User user = userMapper.loadByPhone(email);
        if (user != null){
            throw new BusinessException("该邮箱已被注册，请直接登录");
        }
        // 根据业务键+email去redis中查
        String emailCodeKey = BaseConstants.VerifyCodeConstant.BUSINESS_REGISTER_PREFIX + email;
        Object emailCodeValue = redisTemplate.opsForValue().get(emailCodeKey);
        String emailCode = "";
        if (emailCodeValue == null){
            emailCode = StrUtils.getComplexRandomString(4);
        } else {
            String[] emailCodeValueArray = emailCodeValue.toString().split(":");
            Long oldTime = Long.valueOf(emailCodeValueArray[1]);
            Long newTime = System.currentTimeMillis();
            if (newTime - oldTime < 1*60*1000){
                throw new BusinessException("请一分钟后重试！");
            }
            emailCode = emailCodeValueArray[0];
        }
        String newSmsCodeValue = emailCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(emailCodeKey, newSmsCodeValue, 3, TimeUnit.MINUTES);
        /*SendComplexEmails.sendEmail("你的验证为：" + emailCode,email);*/
        System.out.println("你的验证为：" + emailCode);
    }
}
